package com.halfsword.creativecraft.recipe;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.halfsword.creativecraft.CreativeCraft;
import net.minecraft.core.NonNullList;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.*;
import net.minecraft.world.level.Level;

import java.util.HashMap;
import java.util.Map;

public class SteamCrusherRecipe extends BaseMachineRecipe {

    // ================= 配方属性 =================
    private final ResourceLocation id;
    private final String group;
    private final NonNullList<Ingredient> inputs;
    private final ItemStack result;
    private final ItemStack byproduct;
    private final int processingTime;

    public SteamCrusherRecipe(ResourceLocation id, String group,
                              NonNullList<Ingredient> inputs,
                              ItemStack result,
                              ItemStack byproduct,
                              int processingTime) {
        super(id,group,inputs,result,processingTime);
        this.id = id;
        this.group = group;
        this.inputs = inputs;
        this.result = result;
        this.byproduct = byproduct;
        this.processingTime = processingTime;
    }

    // ================= 核心方法 =================
    @Override
    public boolean matches(Container container, Level level) {
        // 无序配方匹配（总量匹配）
        Map<Item, Integer> availableCounts = new HashMap<>();

        // 统计容器中的物品
        for (int i = 0; i < container.getContainerSize(); i++) {
            ItemStack stack = container.getItem(i);
            if (!stack.isEmpty()) {
                availableCounts.merge(stack.getItem(), stack.getCount(), Integer::sum);
            }
        }

        // 统计配方需要的物品
        Map<Item, Integer> requiredCounts = new HashMap<>();
        for (Ingredient ingredient : inputs) {
            for (ItemStack matchingStack : ingredient.getItems()) {
                if (!matchingStack.isEmpty()) {
                    requiredCounts.merge(matchingStack.getItem(), matchingStack.getCount(), Integer::sum);
                    break; // 只需要一个匹配项
                }
            }
        }

        // 检查是否满足要求
        for (Map.Entry<Item, Integer> entry : requiredCounts.entrySet()) {
            Item item = entry.getKey();
            int required = entry.getValue();
            int available = availableCounts.getOrDefault(item, 0);

            if (available < required) {
                CreativeCraft.LOGGER.debug("物品 {} 不足: 需要 {}, 实际 {}",
                        item.getDescription(), required, available);
                return false;
            }
        }

        return true;
    }

    @Override
    public ItemStack assemble(Container container, RegistryAccess registryAccess) {
        return result.copy();
    }

    @Override
    public boolean canCraftInDimensions(int width, int height) {
        return true; // 容器大小不影响配方
    }



    public ItemStack getByproduct() {
        return byproduct.copy();
    }

    public int getProcessingTime() {
        return processingTime;
    }

    // ================= 基础方法 =================
    @Override
    public ResourceLocation getId() {
        return id;
    }

    @Override
    public RecipeSerializer<?> getSerializer() {
        return Serializer.INSTANCE;
    }

    @Override
    public RecipeType<?> getType() {
        return Type.INSTANCE;
    }

    @Override
    public String getGroup() {
        return group;
    }

    // ================= 配方序列化器 =================
    public static class Serializer implements RecipeSerializer<SteamCrusherRecipe> {
        public static final Serializer INSTANCE = new Serializer();
        public static final ResourceLocation ID =
                ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "unfried_steam_crushing");

        @Override
        public SteamCrusherRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
            // 1. 解析分组
            String group = GsonHelper.getAsString(json, "group", "");

            // 2. 解析输入原料
            JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients");
            NonNullList<Ingredient> inputs = NonNullList.create();

            for (JsonElement element : ingredients) {
                Ingredient ingredient = Ingredient.fromJson(element, false);
                if (!ingredient.isEmpty()) {
                    inputs.add(ingredient);
                }
            }

            // 3. 解析主输出
            JsonObject resultObj = GsonHelper.getAsJsonObject(json, "result");
            ItemStack result = ShapedRecipe.itemStackFromJson(resultObj);

            // 4. 解析副产品（可选）
            ItemStack byproduct = ItemStack.EMPTY;
            if (json.has("byproduct")) {
                JsonObject byproductObj = GsonHelper.getAsJsonObject(json, "byproduct");
                byproduct = ShapedRecipe.itemStackFromJson(byproductObj);
            }

            // 5. 解析处理时间
            int processingTime = GsonHelper.getAsInt(json, "processing_time", 200);

            return new SteamCrusherRecipe(recipeId, group, inputs, result, byproduct, processingTime);
        }

        @Override
        public SteamCrusherRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
            // 1. 读取分组
            String group = buffer.readUtf();

            // 2. 读取原料
            int ingredientCount = buffer.readVarInt();
            NonNullList<Ingredient> inputs = NonNullList.withSize(ingredientCount, Ingredient.EMPTY);

            for (int i = 0; i < ingredientCount; i++) {
                inputs.set(i, Ingredient.fromNetwork(buffer));
            }

            // 3. 读取主输出
            ItemStack result = buffer.readItem();

            // 4. 读取副产品
            ItemStack byproduct = buffer.readItem();

            // 5. 读取处理时间
            int processingTime = buffer.readVarInt();

            return new SteamCrusherRecipe(recipeId, group, inputs, result, byproduct, processingTime);
        }

        @Override
        public void toNetwork(FriendlyByteBuf buffer, SteamCrusherRecipe recipe) {
            // 1. 写入分组
            buffer.writeUtf(recipe.group);

            // 2. 写入原料
            buffer.writeVarInt(recipe.inputs.size());
            for (Ingredient ingredient : recipe.inputs) {
                ingredient.toNetwork(buffer);
            }

            // 3. 写入主输出
            buffer.writeItem(recipe.result);

            // 4. 写入副产品
            buffer.writeItem(recipe.byproduct);

            // 5. 写入处理时间
            buffer.writeVarInt(recipe.processingTime);
        }
    }

    // ================= 配方类型 =================
    public static class Type implements RecipeType<SteamCrusherRecipe> {
        public static final Type INSTANCE = new Type();
        public static final String ID = "unfried_steam_crushing";
    }
}